#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(int argc, char** argv)
{
	/**
		struct timeval {
		    time_t      tv_sec; // Secondes
		    suseconds_t tv_usec; // Microsecondes
		}
	*/
	struct rusage usage;
	long wallClockTime;
	long cpuTime;

	if (argc == 1)
		printf("Usage: ./runcmd <command> [options]\n");
	else
	{
	      	// Process id of the child process
	      	pid_t cpid;
	      	cpid = fork();

	      	if (cpid == -1) /* Failure */
		{
			perror("Child process creation failed!");
			exit(EXIT_FAILURE);
		}
	      	else if (cpid == 0) /* In the child process */
		{
			printf("Child - running...\n\n");
			execvp(argv[1], argv + 1);
		}
		else  /* In the parent process */
		{
			int status;
	      		(void)waitpid(cpid, &status, 0);

			printf("\n\nChild - terminated. Status: %d\n", status);
		
			printf("\n\nChild - Statistics:\n");
			getrusage(RUSAGE_CHILDREN, &usage);
			
			// Wall Clock Time
			wallClockTime = (usage.ru_utime.tv_sec * 1000) + (usage.ru_utime.tv_usec / 1000);
			printf("Wall-clock time: %6ld millisecondes\n", wallClockTime);

			// CPU time
			cpuTime = (usage.ru_stime.tv_sec * 1000) + (usage.ru_stime.tv_usec / 1000);
			printf("CPU time: %6ld millisecondes\n", cpuTime);

			// Voluntary interruptions
			printf("# Voluntary interruptions: %ld\n", usage.ru_nvcsw);

			// Involuntary interruptions
			printf("# Involuntary interruptions: %ld\n", usage.ru_nivcsw);

			// Page defaults
			printf("# Page defaults: %ld\n", usage.ru_majflt);

			// Page reclaims
			printf("# Page reclaims: %ld\n", usage.ru_minflt);
		}
    	}
  return 0;
}

